from flask import Flask, jsonify, request
from flask_cors import CORS
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_jwt_extended import JWTManager
from datetime import datetime
import os
from dotenv import load_dotenv

# 加载环境变量
load_dotenv()

# 创建 Flask 应用
app = Flask(__name__)

# 配置
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY', 'your-secret-key-change-in-production')
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL', 'mysql+pymysql://root:123456@localhost:3306/liuyun')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['JWT_SECRET_KEY'] = os.getenv('JWT_SECRET_KEY', 'jwt-secret-change-in-production')

# 初始化扩展
db = SQLAlchemy(app)
migrate = Migrate(app, db)
jwt = JWTManager(app)

# 配置CORS，支持小程序访问
CORS(app, resources={
    r"/api/*": {
        "origins": ["*"],
        "methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
        "allow_headers": ["Content-Type", "Authorization", "X-Requested-With"],
        "supports_credentials": False
    }
})

# 数据模型
class User(db.Model):
    __tablename__ = 'users'
    
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False, index=True)
    email = db.Column(db.String(120), unique=True, nullable=False, index=True)
    password_hash = db.Column(db.String(128))
    phone = db.Column(db.String(20))
    avatar = db.Column(db.String(255))  # 头像URL
    role = db.Column(db.String(20), default='student')  # student, teacher, admin
    status = db.Column(db.String(20), default='active')  # active, inactive, banned
    created_at = db.Column(db.DateTime, default=datetime.utcnow, index=True)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # 关联关系
    enrollments = db.relationship('Enrollment', backref='student', lazy=True)
    taught_courses = db.relationship('Course', backref='teacher', lazy=True, foreign_keys='Course.teacher_id')

    def to_dict(self):
        return {
            'id': self.id,
            'username': self.username,
            'email': self.email,
            'phone': self.phone,
            'avatar': self.avatar,
            'role': self.role,
            'status': self.status,
            'created_at': self.created_at.isoformat(),
            'updated_at': self.updated_at.isoformat()
        }

class Course(db.Model):
    __tablename__ = 'courses'
    
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(200), nullable=False, index=True)
    description = db.Column(db.Text)
    cover_image = db.Column(db.String(255))  # 课程封面
    category_id = db.Column(db.Integer, db.ForeignKey('categories.id'))
    teacher_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    duration = db.Column(db.Integer)  # 课程时长（分钟）
    price = db.Column(db.Numeric(10, 2), default=0.00)
    original_price = db.Column(db.Numeric(10, 2))  # 原价
    difficulty = db.Column(db.String(20), default='beginner')  # beginner, intermediate, advanced
    status = db.Column(db.String(20), default='draft')  # draft, published, archived
    max_students = db.Column(db.Integer, default=0)  # 最大学生数，0表示无限制
    rating = db.Column(db.Float, default=0.0)  # 平均评分
    rating_count = db.Column(db.Integer, default=0)  # 评分人数
    view_count = db.Column(db.Integer, default=0)  # 浏览次数
    created_at = db.Column(db.DateTime, default=datetime.utcnow, index=True)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # 关联关系
    enrollments = db.relationship('Enrollment', backref='course', lazy=True)
    lessons = db.relationship('Lesson', backref='course', lazy=True, cascade='all, delete-orphan')
    reviews = db.relationship('Review', backref='course', lazy=True)

    def to_dict(self):
        return {
            'id': self.id,
            'title': self.title,
            'description': self.description,
            'cover_image': self.cover_image,
            'category_id': self.category_id,
            'teacher_id': self.teacher_id,
            'teacher_name': self.teacher.username if self.teacher else None,
            'duration': self.duration,
            'price': float(self.price) if self.price else 0.0,
            'original_price': float(self.original_price) if self.original_price else None,
            'difficulty': self.difficulty,
            'status': self.status,
            'max_students': self.max_students,
            'rating': self.rating,
            'rating_count': self.rating_count,
            'view_count': self.view_count,
            'created_at': self.created_at.isoformat(),
            'updated_at': self.updated_at.isoformat()
        }

class Category(db.Model):
    __tablename__ = 'categories'
    
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False, unique=True)
    description = db.Column(db.Text)
    icon = db.Column(db.String(255))  # 分类图标
    parent_id = db.Column(db.Integer, db.ForeignKey('categories.id'))  # 父分类ID
    sort_order = db.Column(db.Integer, default=0)  # 排序
    status = db.Column(db.String(20), default='active')  # active, inactive
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # 关联关系
    courses = db.relationship('Course', backref='category', lazy=True)
    children = db.relationship('Category', backref=db.backref('parent', remote_side=[id]), lazy=True)

    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'description': self.description,
            'icon': self.icon,
            'parent_id': self.parent_id,
            'sort_order': self.sort_order,
            'status': self.status,
            'created_at': self.created_at.isoformat(),
            'updated_at': self.updated_at.isoformat()
        }

class Lesson(db.Model):
    __tablename__ = 'lessons'
    
    id = db.Column(db.Integer, primary_key=True)
    course_id = db.Column(db.Integer, db.ForeignKey('courses.id'), nullable=False)
    title = db.Column(db.String(200), nullable=False)
    description = db.Column(db.Text)
    video_url = db.Column(db.String(255))  # 视频地址
    duration = db.Column(db.Integer)  # 课时时长（秒）
    sort_order = db.Column(db.Integer, default=0)  # 排序
    is_free = db.Column(db.Boolean, default=False)  # 是否免费试看
    status = db.Column(db.String(20), default='published')  # draft, published
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

    def to_dict(self):
        return {
            'id': self.id,
            'course_id': self.course_id,
            'title': self.title,
            'description': self.description,
            'video_url': self.video_url,
            'duration': self.duration,
            'sort_order': self.sort_order,
            'is_free': self.is_free,
            'status': self.status,
            'created_at': self.created_at.isoformat(),
            'updated_at': self.updated_at.isoformat()
        }

class Enrollment(db.Model):
    __tablename__ = 'enrollments'
    
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    course_id = db.Column(db.Integer, db.ForeignKey('courses.id'), nullable=False)
    price_paid = db.Column(db.Numeric(10, 2))  # 实际支付金额
    status = db.Column(db.String(20), default='active')  # active, completed, cancelled
    progress = db.Column(db.Float, default=0.0)  # 学习进度（0-100）
    enrolled_at = db.Column(db.DateTime, default=datetime.utcnow, index=True)
    completed_at = db.Column(db.DateTime)
    
    # 复合索引
    __table_args__ = (db.UniqueConstraint('user_id', 'course_id', name='unique_enrollment'),)

    def to_dict(self):
        return {
            'id': self.id,
            'user_id': self.user_id,
            'course_id': self.course_id,
            'price_paid': float(self.price_paid) if self.price_paid else 0.0,
            'status': self.status,
            'progress': self.progress,
            'enrolled_at': self.enrolled_at.isoformat(),
            'completed_at': self.completed_at.isoformat() if self.completed_at else None
        }

class Review(db.Model):
    __tablename__ = 'reviews'
    
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    course_id = db.Column(db.Integer, db.ForeignKey('courses.id'), nullable=False)
    rating = db.Column(db.Integer, nullable=False)  # 1-5星评分
    comment = db.Column(db.Text)
    status = db.Column(db.String(20), default='published')  # draft, published, hidden
    created_at = db.Column(db.DateTime, default=datetime.utcnow, index=True)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # 关联关系
    user = db.relationship('User', backref='reviews')
    
    # 复合索引
    __table_args__ = (db.UniqueConstraint('user_id', 'course_id', name='unique_review'),)

    def to_dict(self):
        return {
            'id': self.id,
            'user_id': self.user_id,
            'course_id': self.course_id,
            'username': self.user.username if self.user else None,
            'rating': self.rating,
            'comment': self.comment,
            'status': self.status,
            'created_at': self.created_at.isoformat(),
            'updated_at': self.updated_at.isoformat()
        }

# 错误处理
@app.errorhandler(404)
def not_found(error):
    return jsonify({'error': '资源未找到'}), 404

@app.errorhandler(400)
def bad_request(error):
    return jsonify({'error': '请求参数错误'}), 400

@app.errorhandler(500)
def internal_error(error):
    return jsonify({'error': '服务器内部错误'}), 500

# API 路由

# 健康检查接口
@app.route('/api/health', methods=['GET'])
def health_check():
    """
    健康检查接口 - 测试服务是否正常运行
    """
    from datetime import datetime
    
    return jsonify({
        'status': 'healthy',
        'message': '服务运行正常',
        'timestamp': datetime.utcnow().isoformat(),
        'version': '1.0.0',
        'database': 'connected',  # 简单返回连接状态
        'environment': os.getenv('FLASK_ENV', 'production')
    }), 200

# 测试接口
@app.route('/api/health/test', methods=['GET'])
def health_test():
    """
    测试接口 - 用于功能测试
    """
    from datetime import datetime
    
    # 获取请求参数
    test_param = request.args.get('param', 'default_value')
    
    # 测试数据库连接
    try:
        db.session.execute('SELECT 1')
        db_status = 'connected'
    except Exception as e:
        db_status = f'error: {str(e)}'
    
    return jsonify({
        'status': 'test_success',
        'message': '测试接口调用成功',
        'timestamp': datetime.utcnow().isoformat(),
        'test_param': test_param,
        'database_status': db_status,
        'request_method': request.method,
        'request_headers': dict(request.headers),
        'environment': os.getenv('FLASK_ENV', 'production'),
        'version': '1.0.0'
    }), 200

# 创建数据库表
with app.app_context():
    db.create_all()

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=8888) 